package io.renren.manage;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.renren.membermanage.entity.ModelTrain;
import io.renren.membermanage.service.ModelTrainService;
import io.renren.membermanage.service.TaskService;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
@Component
public class TaskQueueManage {

    private final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
    private final ExecutorService executorService;
    @Resource
    private ModelTrainService modelTrainService;
    @Resource
    private TaskService taskService;

    public TaskQueueManage() {
        // 创建单线程线程池
        executorService = Executors.newSingleThreadExecutor();
    }

    @PostConstruct
    public void init() {
        // 在项目启动时初始化任务处理线程
        executorService.submit(this::processTasks);
        //检查库中是否有未执行的任务
        LambdaQueryWrapper<ModelTrain> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelTrain::getStatus, 3);
        queryWrapper.isNotNull(ModelTrain::getTrainParam)
                .and(wrapper -> wrapper.ne(ModelTrain::getTrainParam, ""));
        List<ModelTrain> modelTrainList = modelTrainService.list(queryWrapper);
        if (CollUtil.isNotEmpty(modelTrainList)){
            //如果存在重新添加至队列
            modelTrainList.forEach(item -> {
                Runnable task = taskService.createTask(item);
                this.submitTask(task);
            });
        }
    }


    // 提交任务到队列
    public void submitTask(Runnable task) {
        taskQueue.add(task);
    }

    // 处理队列中的任务
    private void processTasks() {
        while (true) {
            try {
                // 从队列中取出任务，队列为空时会阻塞等待
                Runnable task = taskQueue.take();
                // 执行任务
                try {
                    task.run();
                } catch (Exception e) {
                    // TODO 记录异常日志。这里可以将日志记录数据库
                    log.error("Task execution failed: ", e);
                }
            } catch (InterruptedException e) {
                // 如果线程被中断，重新设置中断状态
                Thread.currentThread().interrupt();
                // 检查是否需要退出
                if (executorService.isShutdown()) {
                    break;
                }
            }
        }
    }

    // 关闭线程池（在应用关闭时调用）
    @PreDestroy
    public void shutdown() {
        // 停止接收新任务
        executorService.shutdown();
        try {
            // 等待已提交的任务完成，最多等待5分钟
            if (!executorService.awaitTermination(300, TimeUnit.SECONDS)) {
                // 如果任务未完成，强制关闭线程池
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            // 如果在等待过程中被中断，强制关闭线程池
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}
